package com.test;

import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;

public class ExcelMergeUtil implements CellWriteHandler{

	private int[] mergeColumnIndex;
	private int mergeRowIndex;

	public ExcelMergeUtil() {
	}

	public ExcelMergeUtil(int mergeRowIndex, int[] mergeColumnIndex) {
		this.mergeRowIndex = mergeRowIndex;
		this.mergeColumnIndex = mergeColumnIndex;
	}

	@Override
	public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
			Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

	}

	@Override
	public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
			Head head, Integer relativeRowIndex, Boolean isHead) {

	}

	@SuppressWarnings("rawtypes")
	@Override
	public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
			CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

	}

	@SuppressWarnings("rawtypes")
	@Override
	public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
			List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

		// 当前行
		int curRowIndex = cell.getRowIndex();
		// 当前列
		int curColIndex = cell.getColumnIndex();

		if (curRowIndex > mergeRowIndex) {
			for (int i = 0; i < mergeColumnIndex.length; i++) {
				if (curColIndex == mergeColumnIndex[i]) {
					mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
					break;
				}
			}
		}
	}

	/**
	 * 当前单元格向上合并
	 *
	 * @param writeSheetHolder
	 * @param cell
	 *            当前单元格
	 * @param curRowIndex
	 *            当前行
	 * @param curColIndex
	 *            当前列
	 */
	@SuppressWarnings("deprecation")
	private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
		Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue()
				: cell.getNumericCellValue();
		Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
		Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue()
				: preCell.getNumericCellValue();
		// 将当前单元格数据与上一个单元格数据比较
		Boolean dataBool = preData.equals(curData);
		// 此处需要注意：因为我是按照订单号确定是否需要合并的，所以获取每一行第二列数据和上一行第一列数据进行比较，如果相等合并
		Boolean bool = cell.getRow().getCell(0).getStringCellValue()
				.equals(cell.getSheet().getRow(curRowIndex - 1).getCell(0).getStringCellValue());
		if (dataBool && bool) {
			Sheet sheet = writeSheetHolder.getSheet();
			List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
			boolean isMerged = false;
			for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
				CellRangeAddress cellRangeAddr = mergeRegions.get(i);
				// 若上一个单元格已经被合并，则先移出原有的合并单元，再重新添加合并单元
				if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
					sheet.removeMergedRegion(i);
					cellRangeAddr.setLastRow(curRowIndex);
					sheet.addMergedRegion(cellRangeAddr);
					isMerged = true;
				}
			}
			// 若上一个单元格未被合并，则新增合并单元
			if (!isMerged) {
				CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex,
						curColIndex);
				sheet.addMergedRegion(cellRangeAddress);
			}
		}
	}
}
